home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / AOCE Sample Code / PowerTalk Access Modules / Sample SMSAM / SampleSMSAM Source / TupleDatabase / DiskLog.h < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-28  |  9.8 KB  |  312 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        DiskLog.h
  3.  
  4.     Copyright:    © 1991-1994 by Apple Computer, Inc.
  5.                 All rights reserved.
  6.  
  7.     Part of the AOCE Sample SMSAM Package.  Consult the license
  8.     which came with this software for your specific legal rights.
  9.  
  10. */
  11.  
  12.  
  13.  
  14. #ifndef    __DISKLOG__
  15. #define    __DISKLOG__
  16.  
  17. #ifndef    __TYPES__
  18. #include "Types.h"
  19. #endif
  20.  
  21. #ifndef    __DISKENTRY__
  22. #include "DiskEntry.h"
  23. #endif
  24.  
  25. #ifndef    __DIRECTOBJECT__
  26. #include "DirectObject.h"
  27. #endif
  28.  
  29. #pragma push
  30. #pragma segment DiskLog
  31.  
  32. // forward declarations
  33. class ostream;
  34. class TFileSpec;
  35. class TPurgeCriteria;
  36. class TSemaphore;
  37. class TAbstractFile;
  38. class TLogEntry;
  39.  
  40. /*============================================================================
  41.  
  42.     TDiskLog is a class which represents a storage place for entries, objects
  43.     which contain information which must be persistent and stored in on disk.
  44.     The file which contains the log entries is determined by the TFileSpec
  45.     object passed to the log on instantiation.
  46.  
  47.     A log contains 1..CountEntries() entries, and each entry within a log
  48.     is assigned a unique serial number within that log. Entries added to
  49.     logs must be subclasses of TLogEntry (see LogEntry.h). The maxmimum
  50.     number of entries which can be placed in a log is only limited by the
  51.     amount of free disk space available.
  52.  
  53.     Entries are placed in a log using AddEntry(). However, the caller still
  54.     owns the entry object being added. An image of the entry is immediately
  55.     written to the log’s file. The entry is also assigned a new EntryID.
  56.  
  57.     Entries can be retrieved from a log using CreateEntry() which requires
  58.     the user to supply an index of the desired entry. The caller owns the
  59.     object returned by CreateEntry(). TDiskLogEnumerator and TDiskLogIterator are
  60.     classes which perform advanced mult-user access to log contents.
  61.  
  62.     A log also has the capability for purging entries according to a
  63.     TPurgeCriteria object which specifies the EntryIndex of the latest entry
  64.     which can be purged.
  65.  
  66. ----------------------------------------------------------------------------*/
  67.  
  68.  
  69. typedef unsigned long EntryIndex;
  70. typedef unsigned short FormatVersion;
  71. typedef long EntryOffset;
  72.  
  73. typedef struct LogHeader
  74. {
  75.     FormatVersion            fFormatVersion;    // hiword is min entry size, loword is header size
  76.     unsigned long            fEntryCount;
  77.     EntryID                    fFirstEntryID;
  78.     EntryOffset                fLastEntryOffset;
  79.     EntryOffset                fNewEntryOffset;
  80.     EntryIndex    fCurrentEntryIndex;
  81.     EntryOffset                fCurrentEntryOffset;
  82. } LogHeader;
  83.  
  84.  
  85. class TDiskLog : public TDirectObject
  86. {
  87. public:
  88.  
  89.     enum LogPermission { kRewrite, kAppend, kRead, kNoneOfTheAbove };
  90.  
  91.     static const EntryIndex kInvalidIndex;
  92.  
  93.             TDiskLog ( const TFileSpec&, TPurgeCriteria* = nil );
  94.     virtual    ~TDiskLog ();
  95.  
  96. // log control
  97.  
  98.     virtual    Boolean                    Open ( LogPermission = kAppend );
  99.     virtual    Boolean                    Close ();
  100.     virtual    Boolean                    Delete ();
  101.  
  102. // entry access
  103.  
  104.     virtual    Boolean                    AddEntry ( TLogEntry& );
  105.     virtual    TLogEntry*                CreateEntry ( EntryIndex );
  106.     virtual    Boolean                    RemoveUntil ( EntryIndex );
  107.             EntryIndex                CountEntries ();
  108.             Boolean                    IsValidIndex ( EntryIndex );
  109.  
  110. // wrapping criteria
  111.  
  112.     virtual    void                    AdoptPurgeCriteria ( TPurgeCriteria* );
  113.     virtual    TPurgeCriteria*            OrphanPurgeCriteria ();
  114.             const TPurgeCriteria*    GetPurgeCriteria () const;
  115.  
  116. // file typing
  117.  
  118.     virtual    OSType                    GetLogFileCreator () const;
  119.     virtual    OSType                    GetLogFileType () const;
  120.  
  121. /***********************************|****************************************/
  122.  
  123. // the following methods are for protected use and/or debugging only
  124.  
  125. #ifndef debug
  126.     protected:
  127. #endif
  128.  
  129.     static    void                    DumpLog ( ostream& );
  130.     static    void                    DumpLog ( ostream&, const FSSpec& );
  131.  
  132.     virtual    Boolean                    InvariantCheck ( ostream& ) const;
  133.     virtual    ostream&                operator >> ( ostream& ) const;
  134.  
  135.  
  136. // interface for reading and writing entries
  137.  
  138.     // these handle the entire internal file format
  139.  
  140.     virtual    Boolean                    WriteNewEntry ( TLogEntry& );
  141.     virtual    Boolean                    FlattenFromCurrentMark ( TLogEntry& );
  142.     virtual    TLogEntry*                ResurrectFromCurrentMark ();
  143.     virtual    TLogEntry*                ScavengeFromMark ();
  144.     virtual    Boolean                    HandleError ( OSErr, const char* file = nil, unsigned long line = 0 );
  145.  
  146.     // methods for directing to entries in the file
  147.  
  148.     virtual    Boolean                    MoveToValidEntry ( EntryIndex );
  149.     virtual    Boolean                    MoveToNextEntry ();
  150.     virtual    Boolean                    MoveToPreviousEntry ();
  151.  
  152.     // by default, the following two routines handle polymorphic entries
  153.     // override to handle more compact entry storage for monomorphic entry logs
  154.  
  155.     virtual    Boolean                    WriteEntryReconstructInfoAtCurrentMark ( const TLogEntry& );
  156.     virtual    TLogEntry*                ReconstructEntryFromInfoAtCurrentMark ();
  157.  
  158.     virtual    Boolean                    WritePolymorphicEntryReconstructInfoAtCurrentMark ( const TLogEntry& );
  159.     virtual    TLogEntry*                ReconstructPolymorphicEntryFromInfoAtCurrentMark ();
  160.  
  161.     // these are general purpose
  162.  
  163.     virtual    Boolean                    ValidateDiskContents ( ostream& );
  164.     virtual    Boolean                    EnsureUsabilityOnceOpen ( LogPermission );
  165.  
  166. // this is loaded to and dumped from the start of the log file
  167.  
  168.     virtual    Boolean                    LoadHeaderInfo ();
  169.     virtual    Boolean                    DumpHeaderInfo ();
  170.     virtual    Boolean                    ValidateHeaderContents ( const struct LogHeader&, unsigned long fileEnd ) const;
  171.     virtual    void                    InitializeHeaderValues ( struct LogHeader& ) const;
  172.  
  173.     virtual    FormatVersion            GetFormatVersion () const;
  174.     virtual    Boolean                    HandleUnexpectedVersion ( FormatVersion );
  175.  
  176.             EntryIndex                MapToIndex ( EntryID ) const;
  177.             EntryID        MapToID ( EntryIndex ) const;
  178.             Boolean                    IsValidOffset ( EntryOffset ) const;
  179.  
  180. private:    TDiskLog ( const TDiskLog& );        // operation not defined
  181.             TDiskLog&                operator = ( const TDiskLog& );    // operation not defined
  182.  
  183.             LogHeader                fHeader;
  184.  
  185.     // this is runtime-only info
  186.  
  187.             TAbstractFile*            fFile;
  188.             TPurgeCriteria*            fCriteria;
  189.             LogPermission            fPermission;
  190.  
  191.     friend class TDiskLogEnumerator;
  192.     friend class TDiskLogIterator;
  193. };
  194.  
  195. /***********************************|****************************************/
  196.  
  197. class TDiskLogEnumerator : public TDirectObject
  198. {
  199. public:        TDiskLogEnumerator ( TDiskLog& );
  200.     virtual    ~TDiskLogEnumerator ();
  201.  
  202.             EntryIndex    CountEntries () const;
  203.  
  204.             const TLogEntry*        GetEntryByIndex ( EntryIndex );
  205.             TLogEntry*                AdoptEntryByIndex ( EntryIndex );
  206.  
  207.             const TLogEntry*        GetEntryByID ( EntryID );
  208.             TLogEntry*                AdoptEntryByID ( EntryID );
  209. #if debug
  210.     virtual    Boolean                    InvariantCheck ( ostream& ) const;
  211.     virtual    ostream&                operator >> ( ostream& ) const;
  212. #endif
  213.  
  214. protected:                            TDiskLogEnumerator ();                        // operation not defined
  215.             TDiskLogEnumerator&        operator = ( const TDiskLogEnumerator& );    // operation not defined
  216.  
  217.             TDiskLog&                fLog;
  218.             TLogEntry*                fEntryCache;
  219.             EntryID        fFirstEntryID;
  220. };
  221.  
  222. /***********************************|****************************************/
  223.  
  224. class TDiskLogIterator : public TDirectObject
  225. {
  226. public:        TDiskLogIterator ( TDiskLog& );
  227.     virtual    ~TDiskLogIterator ();
  228.  
  229.             const TLogEntry*        GetFirstEntry ();
  230.             TLogEntry*                AdoptFirstEntry ();
  231.  
  232.             const TLogEntry*        GetNextEntry ();
  233.             TLogEntry*                AdoptNextEntry ();
  234.  
  235.             const TLogEntry*        GetLastEntry ();
  236.             TLogEntry*                AdoptLastEntry ();
  237.  
  238.             const TLogEntry*        GetPreviousEntry ();
  239.             TLogEntry*                AdoptPreviousEntry ();
  240. #if debug
  241.     virtual    Boolean                    InvariantCheck ( ostream& ) const;
  242.     virtual    ostream&                operator >> ( ostream& ) const;
  243. #endif
  244.  
  245. private:    TDiskLogIterator ( const TDiskLogIterator& );    // operation not defined
  246.             TDiskLogIterator&        operator = ( const TDiskLogIterator& );        // operation not defined
  247.  
  248.             TDiskLog&                fLog;
  249.             TDiskLogEnumerator        fImplementation;
  250.             EntryIndex    fNextIndex;
  251. };
  252.  
  253. /***********************************|****************************************/
  254.  
  255. class TPurgeCriteria
  256. {
  257. public:
  258.     virtual    EntryIndex    AdviseRemoveUntil ( const TDiskLog& ) = 0;
  259. };
  260.  
  261. /***********************************|****************************************/
  262.  
  263. class TFileSizePurgeCriteria : public TPurgeCriteria
  264. {
  265. public:
  266.     virtual    EntryIndex    AdviseRemoveUntil ( const TDiskLog& );
  267. };
  268.  
  269. /***********************************|****************************************/
  270.  
  271. class TEntryCountCriteria : public TPurgeCriteria
  272. {
  273. public:
  274.     virtual    EntryIndex    AdviseRemoveUntil ( const TDiskLog& );
  275. };
  276.  
  277. /***********************************|****************************************/
  278. /***********************************|****************************************/
  279.  
  280. #ifndef    debug
  281.  
  282. // if we are not debugging, we implement checking as a trivial no-op inline
  283. // functions having zero overhead for production code; that way our clients
  284. // don’t have to #ifdef debug any of their code (and we don’t have to either)
  285.  
  286. inline Boolean TDiskLog::InvariantCheck ( ostream& ) const { return true; }
  287.  
  288. #if debug
  289. inline Boolean TDiskLogEnumerator::InvariantCheck ( ostream& ) const { return true; }
  290. inline Boolean TDiskLogIterator::InvariantCheck ( ostream& ) const { return true; }
  291. #endif
  292.  
  293. #endif    // debug
  294.  
  295. /***********************************|****************************************/
  296.  
  297. inline EntryIndex TDiskLog::CountEntries () { return fHeader.fEntryCount; }
  298. inline Boolean TDiskLog::IsValidIndex ( EntryIndex index ) { return ( index > kInvalidIndex ) && ( index <= fHeader.fEntryCount ); }
  299. inline EntryID TDiskLog::MapToID ( EntryIndex index ) const { return fHeader.fFirstEntryID + ( index - 1 ); }
  300. inline EntryIndex TDiskLog::MapToIndex (  EntryID id ) const { return ( id - fHeader.fFirstEntryID ) + 1; }
  301. inline const TPurgeCriteria* TDiskLog::GetPurgeCriteria () const { return fCriteria; }
  302. inline EntryIndex TDiskLogEnumerator::CountEntries () const { return fLog.CountEntries (); }
  303. inline TLogEntry* TDiskLogEnumerator::AdoptEntryByIndex ( EntryIndex index ) { return fLog.CreateEntry ( index ); }
  304. inline const TLogEntry* TDiskLogEnumerator::GetEntryByID ( EntryID id ) { return GetEntryByIndex ( id - fFirstEntryID + 1 ); }
  305. inline TLogEntry* TDiskLogEnumerator::AdoptEntryByID ( EntryID id ) { return AdoptEntryByIndex ( id - fFirstEntryID + 1 ); }
  306.  
  307. /***********************************|****************************************/
  308.  
  309. #pragma pop
  310.  
  311. #endif    // __DISKLOG__
  312.